From 301c120b7406c824e36a937c0a731d17ccdd5cfd Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 18 Jun 2011 12:45:56 -0400 Subject: [PATCH] toolbar: nth-child support for GtkToolbar This doesn't quite work right yet. --- gtk/gtktoolbar.c | 111 +++++++++++++++++++++++++++++++++++++++++++-- tests/testboxcss.c | 20 ++++---- 2 files changed, 120 insertions(+), 11 deletions(-) diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c index fc687c8d1e..b79cef98e9 100644 --- a/gtk/gtktoolbar.c +++ b/gtk/gtktoolbar.c @@ -121,6 +121,8 @@ struct _GtkToolbarPrivate GTimer *timer; + GtkWidgetPath *sibling_path; + gulong settings_connection; gint idle_id; @@ -226,6 +228,11 @@ static void gtk_toolbar_forall (GtkContainer *contain GtkCallback callback, gpointer callback_data); static GType gtk_toolbar_child_type (GtkContainer *container); +static GtkWidgetPath * gtk_toolbar_get_path_for_child + (GtkContainer *container, + GtkWidget *child); +static void gtk_toolbar_invalidate_order (GtkToolbar *toolbar); + static void gtk_toolbar_orientation_changed (GtkToolbar *toolbar, GtkOrientation orientation); static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar, @@ -395,7 +402,8 @@ gtk_toolbar_class_init (GtkToolbarClass *klass) container_class->child_type = gtk_toolbar_child_type; container_class->get_child_property = gtk_toolbar_get_child_property; container_class->set_child_property = gtk_toolbar_set_child_property; - + container_class->get_path_for_child = gtk_toolbar_get_path_for_child; + klass->orientation_changed = gtk_toolbar_orientation_changed; klass->style_changed = gtk_toolbar_real_style_changed; @@ -3273,11 +3281,12 @@ toolbar_content_new_tool_item (GtkToolbar *toolbar, content->state = NOT_ALLOCATED; content->item = item; content->is_placeholder = is_placeholder; - - gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar)); priv->content = g_list_insert (priv->content, content, pos); + gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar)); + gtk_toolbar_invalidate_order (toolbar); + if (!is_placeholder) { priv->num_children++; @@ -3297,6 +3306,7 @@ toolbar_content_remove (ToolbarContent *content, { GtkToolbarPrivate *priv = toolbar->priv; + gtk_toolbar_invalidate_order (toolbar); gtk_widget_unparent (GTK_WIDGET (content->item)); priv->content = g_list_remove (priv->content, content); @@ -3829,3 +3839,98 @@ toolbar_rebuild_menu (GtkToolShell *shell) gtk_widget_queue_resize (GTK_WIDGET (shell)); } + +typedef struct _CountingData CountingData; +struct _CountingData { + GtkWidget *widget; + gboolean found; + guint before; + guint after; +}; + +static void +count_widget_position (GtkWidget *widget, + gpointer data) +{ + CountingData *count = data; + + if (count->widget == widget) + count->found = TRUE; + else if (count->found) + count->after++; + else + count->before++; +} + +static guint +gtk_toolbar_get_visible_position (GtkToolbar *toolbar, + GtkWidget *child) +{ + CountingData count = { child, FALSE, 0, 0 }; + + /* forall iterates in visible order */ + gtk_container_forall (GTK_CONTAINER (toolbar), + count_widget_position, + &count); + + g_assert (count.found); + + /* FIXME: rtl */ + return count.before; +} + +static void +add_widget_to_path (GtkWidget *widget, + gpointer path) +{ + gtk_widget_path_append_for_widget (path, widget); +} + +static GtkWidgetPath * +gtk_toolbar_get_path_for_child (GtkContainer *container, + GtkWidget *child) +{ + GtkWidgetPath *path; + GtkToolbar *toolbar; + GtkToolbarPrivate *priv; + + toolbar = GTK_TOOLBAR (container); + priv = toolbar->priv; + + if (priv->sibling_path == NULL) + { + priv->sibling_path = gtk_widget_path_new (); + /* forall iterates in visible order */ + gtk_container_forall (container, + add_widget_to_path, + priv->sibling_path); + } + + path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container))); + if (gtk_widget_get_visible (child)) + gtk_widget_path_append_with_siblings (path, + priv->sibling_path, + gtk_toolbar_get_visible_position (toolbar, + child)); + else + gtk_widget_path_append_for_widget (path, child); + + return path; +} + +static void +gtk_toolbar_invalidate_order (GtkToolbar *toolbar) +{ + GtkToolbarPrivate *priv = toolbar->priv; + + if (priv->sibling_path != NULL) + { + gtk_widget_path_unref (priv->sibling_path); + priv->sibling_path = NULL; + + gtk_container_foreach (GTK_CONTAINER (toolbar), + (GtkCallback) gtk_widget_reset_style, + NULL); + } +} + diff --git a/tests/testboxcss.c b/tests/testboxcss.c index bb258f67b0..4a5d43999e 100644 --- a/tests/testboxcss.c +++ b/tests/testboxcss.c @@ -30,11 +30,13 @@ " background-image: none;\n" \ " background-color: red;\n" \ " border-color: black;\n" \ + " color: red;\n" \ " border-radius: 0;\n" \ "}\n" \ "\n" \ ".play:nth-child(even) {\n" \ - " background-color: yellow\n" \ + " background-color: yellow;\n" \ + " color: green;\n" \ "}\n" \ "\n" \ ".play:nth-child(first) {\n" \ @@ -96,14 +98,14 @@ remove_widget (GtkWidget *widget) } static void -add_widget (GtkBox *box) +add_widget (GtkToolbar *box) { static int count = 0; GtkWidget* button; char *text; text = g_strdup_printf ("Remove %d", ++count); - button = gtk_button_new_from_stock (text); + button = (GtkWidget *)gtk_tool_button_new (NULL, text); g_free (text); gtk_style_context_add_class (gtk_widget_get_style_context (button), "play"); g_signal_connect_swapped (button, @@ -112,6 +114,7 @@ add_widget (GtkBox *box) button); gtk_widget_show (button); gtk_container_add (GTK_CONTAINER (box), button); + g_print ("path: %s\n", gtk_widget_path_to_string (gtk_widget_get_path (button))); } static void @@ -152,7 +155,8 @@ main (gint argc, gchar **argv) main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add (GTK_CONTAINER (window), main_box); - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + box = gtk_toolbar_new (); + gtk_toolbar_set_style (GTK_TOOLBAR (box), GTK_TOOLBAR_TEXT); gtk_box_pack_start (GTK_BOX (main_box), box, FALSE, TRUE, 0); container = gtk_scrolled_window_new (NULL, NULL); @@ -191,10 +195,10 @@ main (gint argc, gchar **argv) box); gtk_box_pack_end (GTK_BOX (container), child, FALSE, FALSE, 0); - add_widget (GTK_BOX (box)); - add_widget (GTK_BOX (box)); - add_widget (GTK_BOX (box)); - add_widget (GTK_BOX (box)); + add_widget (GTK_TOOLBAR (box)); + add_widget (GTK_TOOLBAR (box)); + add_widget (GTK_TOOLBAR (box)); + add_widget (GTK_TOOLBAR (box)); gtk_widget_show_all (window); -- 2.30.2